/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2021-01-14
*/
package com.rzico.account.service;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.rzico.account.entity.PhonePayment;
import com.rzico.account.entity.Refunds;
import com.rzico.account.model.Attach;
import com.rzico.base.BaseMapper;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.account.entity.PhoneRefunds;
import com.rzico.basics.entity.Enterprise;
import com.rzico.basics.service.EnterpriseService;
import com.rzico.core.entity.SysMch;
import com.rzico.core.entity.SysPlugin;
import com.rzico.core.plugin.PaymentPlugin;
import com.rzico.core.service.SysMchService;
import com.rzico.core.service.SysPluginService;
import com.rzico.exception.CustomException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.rzico.account.mapper.PhoneRefundsMapper;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * <pre>
 * 豆讯话费退款单业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
public class PhoneRefundsService extends BaseServiceImpl<PhoneRefunds, String> {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private PhoneRefundsMapper phoneRefundsMapper;

    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired
    protected SysPluginService sysPluginService;

    @Autowired
    private SysMchService sysMchService;

    @Autowired
    private PhonePaymentService phonePaymentService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public BaseMapper<PhoneRefunds, String> getMapper() {
        return phoneRefundsMapper;
    }

    /**
     * 发起退款
     * @param id
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void refundSubmit(Long id) throws Exception {

        PhoneRefunds phoneRefunds = findById(id);
        if (phoneRefunds != null) {

            Enterprise enterprise = enterpriseService.findById(phoneRefunds.getEnterpriseId());

            SysMch sysMch = sysMchService.selectByPrimaryKey(enterprise.getMchId());
            if (sysMch.getMchType().equals(2)) {
                //特约商户,服务商代收
                enterprise = enterpriseService.findByMch(sysMch.getIsvId());
            }

            SysPlugin sysPlugin = sysPluginService.findByPlugin(enterprise.getMchId(),phoneRefunds.getPaymentPluginId());
            if (sysPlugin==null) {
                phoneRefunds.setTranSn("没有安装插件");
                updateByPrimaryKeySelective(phoneRefunds);
                return;
            }

            PhonePayment phonePayment = phonePaymentService.selectByPrimaryKey(phoneRefunds.getPaymentId());

            PaymentPlugin paymentPlugin = sysPluginService.getPaymentPlugin(phoneRefunds.getPaymentPluginId());

            Map<String,Object> data = paymentPlugin.refund(sysPlugin,phoneRefunds.getSn(),phonePayment.getSn(),phonePayment.getAmount(),phoneRefunds.getAmount(),null);
            if ("0000".equals(data.get("return_code").toString())) {
                //提交成功后，等待查询结果
                phoneRefunds.setTranSn(String.valueOf(data.get("tranSn")));
                phoneRefunds.setStatus(Refunds.STATUS_SUCCESS);
                updateByPrimaryKeySelective(phoneRefunds);
            } else {
                throw new CustomException(data.get("error_msg").toString());
            }

        }

    }

    /**
     * 查询退款结果
     * @param id
     * @throws Exception
     */
    public void refundQuery(Long id) throws Exception {

        PhoneRefunds phoneRefunds = selectByPrimaryKey(id);

        PaymentPlugin paymentPlugin = sysPluginService.getPaymentPlugin(phoneRefunds.getPaymentPluginId());

        Enterprise enterprise = enterpriseService.findById(phoneRefunds.getEnterpriseId());


        SysMch sysMch = sysMchService.selectByPrimaryKey(enterprise.getMchId());
        if (sysMch.getMchType().equals(2)) {
            //特约商户,服务商代收
            enterprise = enterpriseService.findByMch(sysMch.getIsvId());
        }


        SysPlugin sysPlugin = sysPluginService.findByPlugin(enterprise.getMchId(),phoneRefunds.getPaymentPluginId());
        if (sysPlugin==null) {
            return;
        }
        Map<String,Object> resultMap = null;

        if ("alipayAppPlugin".equals(sysPlugin.getPluginId())) {
            PhonePayment phonePayment = phonePaymentService.selectByPrimaryKey(phoneRefunds.getPaymentId());
            resultMap = refundQuery(sysPlugin,phoneRefunds.getSn(),phonePayment.getSn(),null);
        } else {
            resultMap = paymentPlugin.refundQuery(sysPlugin,phoneRefunds.getSn(),phoneRefunds.getTranSn(),null);
        }

        if ("0000".equals(resultMap.get("return_code").toString())) {
            try {
                handle(phoneRefunds.getSn(),resultMap.get("tranSn").toString());
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        } else {
            if (!"0001".equals(resultMap.get("return_code").toString()) && !"9999".equals(resultMap.get("return_code").toString())) {
                phoneRefunds.setStatus(Refunds.STATUS_FAILURE);
                updateByPrimaryKeySelective(phoneRefunds);
            }
        }

    }

    /**
     *
     * @param sn
     * @param tranSn
     * @throws Exception
     */
    public void handle(String sn,String tranSn) throws Exception {
        PhoneRefunds phoneRefunds = findBySn(sn);
        phoneRefunds.setRefundsDate(new Date());
        phoneRefunds.setStatus(Refunds.STATUS_REFUNDED);
        phoneRefundsMapper.updateByPrimaryKeySelective(phoneRefunds);

        //通过MQ异步通知退款成功
        if (phoneRefunds.getAttach()!=null) {
            Attach attachQueue = phoneRefunds.decodeAttach();
            attachQueue.setCode("0000");
            Message message = MessageBuilder
                    .withBody(JSON.toJSONString(attachQueue).getBytes())
                    .setContentType(MessageProperties.CONTENT_TYPE_JSON)
                    .build();
            CorrelationData correlationData = new CorrelationData();
            correlationData.setId(UUID.randomUUID().toString());
            rabbitTemplate.convertAndSend("directExchange",attachQueue.getQueue()+".key", message, correlationData);
        }

    }

    public PhoneRefunds findBySn(String sn){
        Map<String,Object> params = new HashMap<>();
        params.put("sn",sn);
        List<PhoneRefunds> phoneRefundsList = super.selectList(params);
        if (phoneRefundsList.size()>0) {
            return phoneRefundsList.get(0);
        } else {
            return null;
        }
    }

    /**
     * 查询退款
     */
    public Map<String, Object> refundQuery(SysPlugin sysPlugin, String refundNo, String sn, HttpServletRequest request) {


        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do",
                sysPlugin.getAttribute("appid"),
                sysPlugin.getAttribute("APP_PRIVATE_KEY"),
                "json",
                "UTF-8",
                sysPlugin.getAttribute("ALIPAY_PUBLIC_KEY"),
                "RSA2"
        );


        AlipayTradeFastpayRefundQueryRequest queryRequest = new AlipayTradeFastpayRefundQueryRequest();

        HashMap<String, Object> paramsMap = new HashMap<String, Object>();
        paramsMap.put("out_trade_no",sn);
        paramsMap.put("out_request_no",refundNo);

        HashMap<String, Object> finalpackage = new HashMap<String, Object>();

        try {

            queryRequest.setBizContent(JSON.toJSONString(paramsMap));
            AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(queryRequest);
            if(response.isSuccess()){
                if ("REFUND_SUCCESS".equals(response.getRefundStatus()) || response.getRefundStatus()==null) {
                    finalpackage.put("tranSn", response.getTradeNo());
                    finalpackage.put("return_code", "0000");
                } else {
                    finalpackage.put("return_code", "0003");
                    finalpackage.put("error_msg",response.getSubMsg());
                }
            } else {
                finalpackage.put("return_code", "0003");
                finalpackage.put("error_msg",response.getSubMsg());
            }


        } catch (Exception e) {
            finalpackage.put("return_code", "9999");
            finalpackage.put("error_msg", e.getMessage());
        }
        return finalpackage;

    }


}
